#include <stdarg.h>
#include <corestdio.h>
#include <cstdint.h>
#include <string.h>
#include <_stdlib.h>
void utoa(unsigned int value,int base,char *str);
void utoa_s(int value,int base,char *str);

int __vprintf (printf_helper_t __helper,uint32_t impl,const char* str, va_list args) {
	char c;
	char strz[64];
	int iii;
	size_t i;
	if(!str)
		return 0;
	for (i=0; i<strlen(str);i++) {
		switch (str[i]) {
			case '%':
				switch (str[i+1]) {
					/*** characters ***/
			case 'c': {
				c = va_arg (args, char);
				if (__helper(c,impl) != 0)
					return -1;
				i++;		// go to next character
				break;
					  }

					  /*** address of ***/
			case 's': {
				iii = (uint32_t) va_arg (args, uint32_t);
				__vprintf (__helper,impl,(const char*)iii,0);
				i++;		// go to next character
				break;
					  }

					  /*** integers ***/
			case 'd':
			case 'i': {
				iii = va_arg (args, int);
				utoa_s (iii, 10, strz);
				__vprintf (__helper,impl,strz,0);
				i++;		// go to next character
				break;
					  }

					  /*** display in hex ***/
			case 'X':
			case 'x': {
				iii = va_arg (args, int);
				utoa (iii,16,strz);
				__vprintf (__helper,impl,strz,0);
				i++;		// go to next character
				break;
					  }

			default:
				return 1;
				}

				break;

			default:
				if (__helper(str[i],impl) != 0)
					return -1;
				break;
		}

	}
	return i;
}

int __sprintf_helper(char tok,uint32_t impl){
	char **dest = (char**) impl;
	if (tok != 0){
		**dest = tok;
		*dest = (*dest) + 1;
	}
	return 0;
}

int vsprintf(char *dest,const char* str, va_list args){
	char *destey = dest;
	int i =  __vprintf(
		__sprintf_helper,
		(uint32_t) &destey,
		str,	
		args);
	*destey = (char) 0;
	return i;
}

int sprintf(char *dest,const char* str,...){
	va_list args;
	va_start(args,str);
	int res = vsprintf(dest,str,args);
	va_end(args);
	return res;
}